﻿using DtuService;
using SuperSocket.SocketBase;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DtuService
{
    public class HttpClient : Client
    {
        private Encoding charEncoder = Encoding.UTF8;

        private byte[] bBuffer;

        public HttpClient(ByteSession http)
            : base(http)
        {

        }
        
        public bool ProcessReceive(byte[] buffer, Action<object, string, string[]> callBack) //接收异步事件返回的数据，用于对数据进行缓存和分包
        {
            String content = String.Empty;
            this.bBuffer = buffer;
            if (bSession == null)
            {
                return false;
            }
            try
            {
                if (buffer.Length > 0)
                {
                    content = Encoding.ASCII.GetString(this.bBuffer);
                    processCommand(content, callBack);
                }
                else
                {
                    Shutdown();
                }
            }
            catch (Exception ex)
            {
                ErrorDisconnected(ex.ToString());
            }
            return true;
        }

        private void processCommand(string content, Action<object, string, string[]> callBack) //处理分完包的数据
        {
            string httpMethod = content.Substring(0, content.IndexOf(" "));

            int start = content.IndexOf(httpMethod) + httpMethod.Length + 1;
            int length = content.LastIndexOf("HTTP") - start - 1;
            string requestedUrl = content.Substring(start, length);
            string Referer = Tools.GetRefererFromHttpHeader(content);
            string requestedHtm = "";
            string[] paramter = null;
            if (httpMethod.Equals("GET"))
            {
                requestedHtm = requestedUrl.Split('?')[0];
                requestedUrl = requestedUrl.Remove(0, requestedUrl.IndexOf('?') + 1);

                paramter = requestedUrl.Split('?');

            }
            else if(httpMethod.Equals("POST"))
            {
                Debug.WriteLog.Log(eLogLevel.ell_Info, "暂不支持POST请求");
                SendResponse("暂不支持POST请求", "501", HttpContentType.HTML);
                return;
            }
            if(!requestedHtm.Contains(".htm"))
            {
                NotFound();
                return;
            }
            requestedHtm = requestedHtm.Replace("/", @"\").Replace("\\", "").Replace(".htm", "");
            callBack(this, requestedHtm, paramter);
            return;
        }
        
        public void NotImplemented()
        {
            SendResponse(
                "<html><head><meta http-equiv=\"Content-Type\" content=\"" + HttpContentType.HTML + "; charset=utf-8\"></head><body><h2>Web Server</h2><div>501 - Not Implemented</div></body></html>",
                "501 Not Implemented", "text/html");

        }

        public void NotFound()
        {
            SendResponse(
                "<html><head><meta http-equiv=\"Content-Type\" content=\"" + HttpContentType.HTML + "; charset=utf-8\"></head><body><h2>Web Server</h2><div>404 - Not Found</div></body></html>",
                "404 Not Found", "text/html");
        }

        public void SendOkResponse(byte[] bContent, string contentType)
        {
            SendResponse(bContent, "200 OK", contentType);
        }

        // For strings
        public void SendResponse(string strContent, string responseCode,
                                  string contentType)
        {
            byte[] bContent = charEncoder.GetBytes(strContent);
            SendResponse(bContent, responseCode, contentType);
        }

        /// <summary>
        /// 响应请求
        /// </summary>
        /// <param name="client"></param>
        /// <param name="bContent">发送的内容</param>
        /// <param name="responseCode"></param>
        /// <param name="contentType"></param>
        public void SendResponse(byte[] bContent, string responseCode,
                                  string contentType)
        {
            try
            {
                byte[] bHeader = charEncoder.GetBytes(
                                    "HTTP/1.1 " + responseCode + "\r\n"
                                  + "Server: Web Server\r\n"
                                  + "Content-Length: " + bContent.Length.ToString() + "\r\n"
                                  + "Connection: close\r\n"
                                  + "Content-Type: " + contentType + "\r\n\r\n");
                if (bSession == null)
                    return;
                SendMessage(bHeader);
                SendMessage(bContent);
                Debug.LogDebug("响应完成");
                Shutdown();
            }
            catch (Exception ex)
            {
                ErrorDisconnected(ex.ToString());
            }
        }
        
        /// <summary>
        /// 网页重定向
        /// </summary>
        /// <param name="client"></param>
        /// <param name="url"></param>
        public void Redirect(string url)
        {
            if (bSession.Connected == true)
            {
                string htmlPage = "<HTML><head> <meta HTTP-EQUIV=\"REFRESH\" content=\"0; url=" + url + "\"></head></HTML>";
                SendResponse(charEncoder.GetBytes(htmlPage), "200 OK", HttpContentType.HTML);
            }
        }

        /// <summary>
        /// 关闭Socket
        /// </summary>
        /// <param name="client"></param>
        /// <param name="msg">output message</param>
        private void ErrorDisconnected(string msg)
        {
            if (bSession != null && bSession.Connected == true )
            {
                try
                {
                    SendResponse(
                        "<html><head><meta http-equiv=\"Content-Type\" content=\"" + HttpContentType.HTML + 
                        "; charset=utf-8\"></head><body><h2>Web Server</h2><div>501 - Method Not Implemented</div></body></html>",
                        "501 Not Implemented", "text/html");
                }
                catch
                {

                }
            }
            Debug.Error(msg);
            Shutdown();
            GC.Collect();
        }
    }
}
